#ifndef ORG_WXW0303_SYMBOL_DB_AUTOCALLUTIL_H
#define ORG_WXW0303_SYMBOL_DB_AUTOCALLUTIL_H

template <typename F>
class GCWhenDtor {
public:
    GCWhenDtor(F &f) noexcept :
        f_(f) {  }

    GCWhenDtor(const GCWhenDtor &) = delete;
    GCWhenDtor(GCWhenDtor &&) = delete;
    GCWhenDtor& operator=(const GCWhenDtor &) = delete;
    GCWhenDtor& operator=(GCWhenDtor &&) = delete;

    bool exec() const noexcept {
        return is_exec;
    }

    void setExec(bool exec) noexcept {
        is_exec = exec;
        return ;
    }

    ~GCWhenDtor() noexcept {
        if (is_exec)
            f_();
    }
private:
    bool is_exec = true;
    F &f_;
};


/// 构建名为 varName 的对象,当该对象析构时,会执行 func() 调用表达式.
#define BUILD_AUTOGC2(varName,func)  GCWhenDtor<decltype(func)> varName(func)
#define BUILD_AUTOGC31(tmpName,line,func) BUILD_AUTOGC2(tmpName ## line,func)
#define BUILD_AUTOGC3(tmpName,line,func) BUILD_AUTOGC31(tmpName, line,func)
#define BUILD_AUTOGC(func) BUILD_AUTOGC3(tmp, __LINE__,func)

/// 注册 func,当退出 AUTOCALL(func) 所处的作用域时,将执行 func() 调用表达式.
#define AUTOCALL(func) BUILD_AUTOGC(func)
#define AUTOCALL2(objName,func) BUILD_AUTOGC2(objName,func)

/**
 * 构建名为 funcName 的 Lambda 表达式.使用:
 * AUTOCALL_FUNC(test_lambda) {
 *     // lambda 表达式的函数体.
 * };  // 不要忘了这里的';'.
 * test_lambda();// 调用 LAMBDA 表达式.
 */
#define AUTOCALL_FUNC(funcName) auto funcName = [&] () noexcept -> void


#endif // ORG_WXW0303_SYMBOL_DB_AUTOCALLUTIL_H
